//
//  GCDTimer.swift
//  Progress
//
//  Created by bin hu on 2025/6/30.
//

import UIKit

public class GCDTimer {
    private var timer: DispatchSourceTimer?
    private let queue = DispatchQueue(label: "com.gcd.timer", attributes: .concurrent)
    private let stateLock = DispatchQueue(label: "com.gcd.timer.state")
    private var _isRunning = false
    
    public var isRunning: Bool {
        return stateLock.sync { _isRunning }
    }
    
    public init() {}
    
    /// 开始timer
    public func start(timeInterval: TimeInterval,
                      repeats: Bool,
                      handle: @escaping () -> Void) {
        stateLock.sync(flags: .barrier) {
            guard !_isRunning else { return }
            
            timer?.cancel()
            
            timer = DispatchSource.makeTimerSource(flags: [], queue: queue)
            timer?.schedule(
                deadline: .now() + (repeats ? timeInterval : 0),
                repeating: repeats ? timeInterval : .infinity
            )
            timer?.setEventHandler { [weak self] in
                handle()
                if !repeats {
                    self?.cancel()
                }
            }
            
            timer?.setCancelHandler { [weak self] in
                self?.stateLock.sync(flags: .barrier) {
                    self?._isRunning = false
                }
            }
            
            _isRunning = true
            timer?.resume()
        }
    }
    
    /// 取消timer
    public func cancel() {
        stateLock.sync(flags: .barrier) {
            guard _isRunning else { return }
            timer?.cancel()
            timer = nil
            _isRunning = false
        }
    }
    
    deinit {
        cancel()
    }
    
}
